home *** CD-ROM | disk | FTP | other *** search
- /*
- Pencil V1.0, Copyright 1994, 95 by Florian Marquardt.
- This program may be distributed under the terms of the GNU general
- public license (Start Pencil and select "Info>COPYING..." for a copy of the
- license).
- */
- // changed 23_10_94: added save/restore for EPS-hack
- #import "PencilImage.h"
- #import <math.h>
-
- extern BOOL globalOutlines;
- extern BOOL movementStatus;
- #define M_180_PI 180.0/M_PI
- extern void expandRect(NXRect *, float, float);
- #define TRANSFORMX(a,b) (tx+sx*cos(phi)*(a)-sy*sin(phi)*(b))
- #define TRANSFORMY(a,b) (ty+sx*sin(phi)*(a)+sy*cos(phi)*(b))
-
- @implementation PencilImage
- - initFromFile:(const char *)filename
- {
- [super init];
- sx=sy=1;
- transformed=NO;
- if(theImage=[NXImage alloc])
- {
- [theImage setDataRetained:YES];
- if([theImage loadFromFile:filename])
- return self;
- else
- {
- [theImage free];
- return nil;
- }
- }
- else
- return nil;
- }
-
- - free
- {
- if(theImage) [theImage free];
- return [super free];
- }
-
- - (BOOL)selected:(NXEvent *)te:(int *)cp:(id)view
- {
- NXPoint pt;
- NXSize thesize;
-
- pt=te->location;
- [self transformPoint:&pt];
- [theImage getSize:&thesize];
- if(pt.x>=0 && pt.y>=0 && pt.x<=thesize.width && pt.y<=thesize.height)
- return(YES);
- else
- return(NO);
- }
-
- - (BOOL)move:(NXEvent *)tte:(int *)cp:(id)view:(float)bsize
- {
- return NO;
- }
-
- - (void)draw:(NXRect *)re
- {
- if(!re || NXIntersectsRect(&bounds, re))
- {
- if(globalOutlines)
- {
- NXSize thesize;
- [theImage getSize:&thesize];
- PSgsave();
- if(translated) PStranslate(tx,ty);
- if(rotated) PSrotate(M_180_PI*phi);
- if(scaled) PSscale(sx,sy);
- PSsetlinewidth(0);
- PSsetgray(.333);
- PSrectstroke(0,0,thesize.width,thesize.height);
- PSgrestore();
- }
- else
- {
- PSgsave();
- if(translated) PStranslate(tx,ty);
- if(rotated) PSrotate(M_180_PI*phi);
- if(scaled) PSscale(sx,sy);
- if([[theImage bestRepresentation] isKindOf:[NXEPSImageRep class]])
- { // Sorry, we need this very UGLY hack, because
- // we want rotated images and therefore we would
- // need "draw", but unfortunately "draw" uses a
- // different DPS context for EPS images (which results in wrong clipping), so...
- char *theEPScode; int length;
- char *thetext;
- NXRect box;
-
- [[(NXEPSImageRep *)[theImage bestRepresentation] getBoundingBox:&box] getEPS:&theEPScode length:&length];
- thetext=(char *)malloc(sizeof(char)*(length+1));
- strncpy(thetext, theEPScode, length);
- thetext[length]=0;
- DPSPrintf(DPSGetCurrentContext(), "0 setgray 0 setlinewidth save %g %g translate\n%s\nrestore\n", -box.origin.x, -box.origin.y, thetext);
- free(thetext);
- }
- else // we need "draw", since we want rotated tiff images, too
- [[theImage bestRepresentation] draw];
- PSgrestore();
- }
- }
- }
-
- - (void)drawPath
- {
- NXSize thesize;
- [theImage getSize:&thesize];
- DPSPrintf(DPSGetCurrentContext()," matrix currentmatrix ");
- if(translated) PStranslate(tx,ty);
- if(rotated) PSrotate(M_180_PI*phi);
- if(scaled) PSscale(sx,sy);
- PSmoveto(0,0);
- PSlineto(thesize.width,0);
- PSlineto(thesize.width,thesize.height);
- PSlineto(0, thesize.height);
- PSclosepath();
- DPSPrintf(DPSGetCurrentContext()," setmatrix\n");
- }
-
- - calculateBoundingBox:(id)view
- {
- float llx, lly, urx, ury;
- NXSize thesize;
-
- [theImage getSize:&thesize];
- llx=lly=0;
- urx=thesize.width;
- ury=thesize.height;
- bounds.origin.x=TRANSFORMX(llx,lly);
- bounds.origin.y=TRANSFORMY(llx,lly);
- bounds.size.width=bounds.size.height=0;
- expandRect(&bounds, TRANSFORMX(llx,ury),TRANSFORMY(llx,ury));
- expandRect(&bounds, TRANSFORMX(urx,ury), TRANSFORMY(urx,ury));
- expandRect(&bounds, TRANSFORMX(urx,lly),TRANSFORMY(urx,lly));
- return self;
- }
-
- - (void)drawControl:(NXRect *)re:(int)cp:(float)bsize
- {
- NXSize thesize;
-
- [theImage getSize:&thesize];
- if(!movementStatus || ![[theImage bestRepresentation] isKindOf:[NXEPSImageRep class]])
- [self draw:re];
- if(transformed) { PSgsave();
- if(translated) PStranslate(tx,ty);
- if(rotated) PSrotate(M_180_PI*phi);
- if(scaled) PSscale(sx,sy);
- }
- PSsetlinewidth(0);
- /* if([[theImage bestRepresentation] isKindOf:[NXEPSImageRep class]])
- {
- PSsetgray(.5);
- PSsetlinewidth(0);
- PSmoveto(0,0);
- PSlineto(thesize.width,thesize.height);
- PSstroke();
- PSmoveto(thesize.width,0);
- PSlineto(0,thesize.height);
- PSstroke();
- }
- PSsetgray(.8);
- PSrectstroke(2,2,thesize.width-4,thesize.height-4);
- */
- PSsetrgbcolor(1,0,0);
- PSsetlinewidth(2);
- #define WW thesize.width*.1
- #define HH thesize.height*.1
- #define HO (thesize.height-2)
- #define WO (thesize.width-2)
- PSmoveto(WW+2,2);
- PSrlineto(-WW,0);
- PSrlineto(0, HH);
- PSstroke();
- PSmoveto(WW+2,HO);
- PSrlineto(-WW,0);
- PSrlineto(0,-HH);
- PSstroke();
- PSmoveto(WO-WW,2);
- PSrlineto(WW,0);
- PSrlineto(0,HH);
- PSstroke();
- PSmoveto(WO-WW,HO);
- PSrlineto(WW,0);
- PSrlineto(0,-HH);
- PSstroke();
- if(transformed) PSgrestore();
- }
-
- - (void)drawIfNeeded:(NXRect *)re:(int)cp:(float)bsize
- { if([[theImage bestRepresentation] isKindOf:[NXEPSImageRep class]]) [self drawControl:re:cp:bsize]; }
- // used for redrawing EPS after a move...
-
- - write:(NXTypedStream *)stream
- {
- [super write:stream];
- NXWriteObject(stream,theImage);
- return self;
- }
-
- - read:(NXTypedStream *)stream
- {
- [super read:stream];
- theImage=NXReadObject(stream);
- return self;
- }
-
- - (void)writeType:(NXStream *)to
- {
- NXPrintf(to,"3");
- }
- @end